import 'dart:io';
import 'dart:convert';
import 'package:mysql1/mysql1.dart';

void main() async {
  // بارلىق IP ئادرېسلاردىن ئۇلىنىشقا يول قويۇش ئۈچۈن
  final server = await HttpServer.bind(InternetAddress.anyIPv4, 8080);
  print('Listening on ${server.address.address}:${server.port}');

  final settings = ConnectionSettings(
    host: 'localhost',
    port: 3306,
    user: 'root', // بۇ يەردە سىزنىڭ ساندان ئىشلەتكۈچى نامىڭىزنى كىرگۈزۈڭ
    password: 'root', // بۇ يەردە سىزنىڭ ساندان پارولىڭىزنى كىرگۈزۈڭ
    db: 'tijarat_sandan',
  );

  // ساندان بىلەن ئۇلىنىشنى سىناپ كۆرۈش
  try {
    final conn = await MySqlConnection.connect(settings);
    print('ساندان ئۇلىنىشى مۇۋەپپەقىيەتلىك بولدى');
    await conn.close();
  } catch (e) {
    print('دىققەت: ساندان ئۇلىنىشى مەغلۇپ بولدى: $e');
    print('لۇتفەن ساندان ئۇچۇرلىرىنى تەكشۈرۈڭ');
  }

  await for (HttpRequest request in server) {
    request.response.headers.add('Access-Control-Allow-Origin', '*');
    request.response.headers
        .add('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
    request.response.headers
        .add('Access-Control-Allow-Headers', 'Origin, Content-Type');

    if (request.method == 'OPTIONS') {
      request.response.statusCode = HttpStatus.ok;
      await request.response.close();
      continue;
    }

    try {
      if (request.uri.path == '/createUserInfoTable') {
        await _checkUserInfoTable(settings, request);
      } else if (request.uri.path == '/createCustomersTable') {
        await _createCustomersTable(settings, request);
      } else if (request.uri.path == '/login') {
        await _login(settings, request);
      } else if (request.uri.path == '/addUser') {
        await _addUser(settings, request);
      } else if (request.uri.path == '/customers') {
        if (request.method == 'GET') {
          await _getCustomers(settings, request);
        } else if (request.method == 'POST') {
          await _addCustomer(settings, request);
        } else if (request.method == 'PUT') {
          await _updateCustomer(settings, request);
        } else if (request.method == 'DELETE') {
          await _deleteCustomer(settings, request);
        }
      } else {
        request.response
          ..statusCode = HttpStatus.notFound
          ..write(json.encode({'success': false, 'message': 'تېپىلمىدى'}));
      }
    } catch (e) {
      print('خاتالىق: $e');
      request.response
        ..statusCode = HttpStatus.internalServerError
        ..write(json.encode({'success': false, 'message': 'خاتالىق: $e'}));
    }

    await request.response.close();
  }
}

Future<void> _createCustomersTable(
    ConnectionSettings settings, HttpRequest request) async {
  try {
    final conn = await MySqlConnection.connect(settings);
    await conn.query('''
      CREATE TABLE IF NOT EXISTS customers (
        id INT AUTO_INCREMENT PRIMARY KEY,
        name VARCHAR(100) NOT NULL,
        phone VARCHAR(20) NOT NULL,
        email VARCHAR(100),
        total_purchases DECIMAL(10,2) DEFAULT 0,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
      )
    ''');

    await conn.close();
    request.response
      ..statusCode = HttpStatus.ok
      ..write(json
          .encode({'success': true, 'message': 'خېرىدارلار جەدۋىلى قۇرۇلدى'}));
  } catch (e) {
    print('خاتالىق: $e');
    request.response
      ..statusCode = HttpStatus.internalServerError
      ..write(json.encode({'success': false, 'message': 'خاتالىق: $e'}));
  }
}

Future<void> _getCustomers(
    ConnectionSettings settings, HttpRequest request) async {
  try {
    final conn = await MySqlConnection.connect(settings);
    final results =
        await conn.query('SELECT * FROM customers ORDER BY created_at DESC');

    final customers = results
        .map((row) => {
              'id': row['id'],
              'name': row['name'],
              'phone': row['phone'],
              'email': row['email'],
              'totalPurchases': row['total_purchases'],
              'createdAt': row['created_at'].toString(),
              'updatedAt': row['updated_at'].toString(),
            })
        .toList();

    await conn.close();
    request.response
      ..statusCode = HttpStatus.ok
      ..write(json.encode({'success': true, 'data': customers}));
  } catch (e) {
    print('خاتالىق: $e');
    request.response
      ..statusCode = HttpStatus.internalServerError
      ..write(json.encode({'success': false, 'message': 'خاتالىق: $e'}));
  }
}

Future<void> _addCustomer(
    ConnectionSettings settings, HttpRequest request) async {
  try {
    final conn = await MySqlConnection.connect(settings);
    final body = await request.cast<List<int>>().transform(utf8.decoder).join();
    final data = json.decode(body);

    final result = await conn.query(
        'INSERT INTO customers (name, phone, email) VALUES (?, ?, ?)',
        [data['name'], data['phone'], data['email']]);

    await conn.close();
    request.response
      ..statusCode = HttpStatus.ok
      ..write(json.encode({
        'success': true,
        'message': 'خېرىدار قوشۇلدى',
        'id': result.insertId
      }));
  } catch (e) {
    print('خاتالىق: $e');
    request.response
      ..statusCode = HttpStatus.internalServerError
      ..write(json.encode({'success': false, 'message': 'خاتالىق: $e'}));
  }
}

Future<void> _updateCustomer(
    ConnectionSettings settings, HttpRequest request) async {
  try {
    final conn = await MySqlConnection.connect(settings);
    final body = await request.cast<List<int>>().transform(utf8.decoder).join();
    final data = json.decode(body);

    await conn.query(
        'UPDATE customers SET name = ?, phone = ?, email = ? WHERE id = ?',
        [data['name'], data['phone'], data['email'], data['id']]);

    await conn.close();
    request.response
      ..statusCode = HttpStatus.ok
      ..write(json.encode({'success': true, 'message': 'خېرىدار يېڭىلاندى'}));
  } catch (e) {
    print('خاتالىق: $e');
    request.response
      ..statusCode = HttpStatus.internalServerError
      ..write(json.encode({'success': false, 'message': 'خاتالىق: $e'}));
  }
}

Future<void> _deleteCustomer(
    ConnectionSettings settings, HttpRequest request) async {
  try {
    final conn = await MySqlConnection.connect(settings);
    final id = request.uri.queryParameters['id'];

    if (id == null) {
      request.response
        ..statusCode = HttpStatus.badRequest
        ..write(json.encode({'success': false, 'message': 'ID كېرەك'}));
      return;
    }

    await conn.query('DELETE FROM customers WHERE id = ?', [id]);

    await conn.close();
    request.response
      ..statusCode = HttpStatus.ok
      ..write(json.encode({'success': true, 'message': 'خېرىدار ئۆچۈرۈلدى'}));
  } catch (e) {
    print('خاتالىق: $e');
    request.response
      ..statusCode = HttpStatus.internalServerError
      ..write(json.encode({'success': false, 'message': 'خاتالىق: $e'}));
  }
}

Future<void> _checkUserInfoTable(
    ConnectionSettings settings, HttpRequest request) async {
  try {
    final conn = await MySqlConnection.connect(settings);
    final tables = await conn.query(
        "SELECT COUNT(*) as count FROM information_schema.tables WHERE table_schema = ? AND table_name = 'userinfo'",
        [settings.db]);
    final tableExists = tables.first['count'] > 0;

    if (tableExists) {
      print('userinfo جەدۋىلى مەۋجۇت');
      await conn.close();
      request.response
        ..statusCode = HttpStatus.ok
        ..write(json
            .encode({'success': true, 'message': 'userinfo جەدۋىلى مەۋجۇت'}));
    } else {
      print('userinfo جەدۋىلى مەۋجۇت ئەمەس');
      await conn.close();
      request.response
        ..statusCode = HttpStatus.notFound
        ..write(json.encode(
            {'success': false, 'message': 'userinfo جەدۋىلى مەۋجۇت ئەمەس'}));
    }
  } catch (e) {
    print('خاتالىق: $e');
    request.response
      ..statusCode = HttpStatus.internalServerError
      ..write(json.encode({'success': false, 'message': 'خاتالىق: $e'}));
  }
}

Future<void> _login(ConnectionSettings settings, HttpRequest request) async {
  try {
    final conn = await MySqlConnection.connect(settings);
    final body = await request.cast<List<int>>().transform(utf8.decoder).join();
    final data = json.decode(body);
    final username = data['username'];
    final password = data['password'];

    final results = await conn.query(
        'SELECT * FROM userinfo WHERE username = ? AND password = ?',
        [username, password]);

    if (results.isNotEmpty) {
      request.response
        ..statusCode = HttpStatus.ok
        ..write(json.encode({'success': true}));
    } else {
      request.response
        ..statusCode = HttpStatus.unauthorized
        ..write(json.encode(
            {'success': false, 'message': 'ئىشلەتكۈچى ئىسمى ياكى پارول خاتا'}));
    }

    await conn.close();
  } catch (e) {
    print('خاتالىق: $e');
    request.response
      ..statusCode = HttpStatus.internalServerError
      ..write(json.encode({'success': false, 'message': 'خاتالىق: $e'}));
  }
}

Future<void> _addUser(ConnectionSettings settings, HttpRequest request) async {
  try {
    final conn = await MySqlConnection.connect(settings);
    final body = await request.cast<List<int>>().transform(utf8.decoder).join();
    final data = json.decode(body);
    final username = data['username'];
    final password = data['password'];

    await conn.query('INSERT INTO userinfo (username, password) VALUES (?, ?)',
        [username, password]);

    request.response
      ..statusCode = HttpStatus.ok
      ..write(json.encode({'success': true}));

    await conn.close();
  } catch (e) {
    print('خاتالىق: $e');
    request.response
      ..statusCode = HttpStatus.internalServerError
      ..write(json.encode({'success': false, 'message': 'خاتالىق: $e'}));
  }
}
